/*
 * Servidor de ping UDP.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "pingudp.h"

#define BACKLOG 5

int main() {
	int sock, yes = 1, aux;
	struct sockaddr_in addr;
	unsigned int size = sizeof addr;
	char msg[LEN] = "";


	/* Cria o socket. */
	sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (sock == -1) {
		perror("Não conseguiu criar o socket do servidor.");
		return EXIT_FAILURE;
	}

	/* Permite que o socket escute na porta, a não ser que já tenha alguém escutando nela. */
	aux = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
	if (aux == -1) {
		perror("Não conseguiu reutilizar a porta de conexão.");
		return EXIT_FAILURE;
	}

	/* Cria o endereço do socket. */
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = INADDR_ANY;
	memset(&addr.sin_zero, 0, 8);


	/* Associa o socket ao seu endereço. */
	if (bind(sock, (struct sockaddr *) &addr, sizeof addr) == -1) {
		perror("Não conseguiu fazer o bind do socket do servidor com a porta.");
		return EXIT_FAILURE;
	}

	/* Fica em loop infinito recebendo e enviando de volta os pacotes do cliente */
	for (;;) {
		aux = recvfrom(sock, msg, LEN, 0, (struct sockaddr *) &addr, &size);
		if (aux <= 0) {
			perror("Erro ao receber mensagem");
			return EXIT_FAILURE;
		}
		aux = sendto(sock, msg, LEN, 0, (struct sockaddr *) &addr, size);
		if (aux <= 0) {
			perror("Erro ao enviar mensagem");
			return EXIT_FAILURE;
		}
		puts(msg);
	}

	close(sock);
	return 0;
}
